/*
 * Copyright (C) 2023 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <iostream>
#include "hilog/log.h"
#include "aki/jsbind.h"
#include "napi/native_api.h"
#include "aki_test_manager.h"

namespace AKITEST {

AkiTestManager AkiTestManager::akiTestManager_;
AkiTestManager &AkiTestManager::GetInstance() { return akiTestManager_; }

void AkiTestManager::AddTestFunction(const std::string apiName, NoParamNoReturnFunc func)
{
    functionMap_[apiName] = func;
}

void AkiTestManager::Start()
{
    for (const auto &it : functionMap_) {
        it.second();
    }
}

napi_env AkiTestManager::GetNapiEnv()
{
    return napiEnv_;
}

void AkiTestManager::SetNapiEnv(napi_env env)
{
    napiEnv_ = env;
}

void AkiTestManager::UpdateTestTime(std::string moduleName, std::string api, int napiTestTime, int akiTestTime)
{
    auto moduleIt = testTimeMap_.find(moduleName);
    TestTimeInfo testTimeInfo{napiTestTime, akiTestTime};
    if (moduleIt == testTimeMap_.end()) {
        std::map<std::string, TestTimeInfo> newApiMap;
        newApiMap[api] = testTimeInfo;
        testTimeMap_.insert({moduleName, newApiMap});
    } else {
        auto &apiMap = moduleIt->second;
        auto apiIt = apiMap.find(api);
        if (apiIt == apiMap.end()) {
            apiMap.insert({api, testTimeInfo});
        } else {
            testTimeInfo = apiIt->second;
            if (napiTestTime) {
                testTimeInfo.testTimeNapi = napiTestTime;
            }
            if (akiTestTime) {
                testTimeInfo.testTimeAki = akiTestTime;
            }
            apiIt->second = testTimeInfo;
        }
    }
}

void AkiTestManager::PrintTestTime()
{
    for (const auto &module : testTimeMap_) {
        OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, "AKITEST", "moduleName:%{public}s\n", module.first.c_str());
        for (const auto &api : module.second) {
            OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, "AKITEST", "\t\tapiName:%{public}s\n", api.first.c_str());
            OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, "AKITEST",
                         "\t\t\t\tNapiTestTime:%{public}d (ns) \t\t AkiTestTime:%{public}d (ns)\n",
                         api.second.testTimeNapi, api.second.testTimeAki);
        }
    }
}

} // namespace AKITEST
